home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QRZ! Ham Radio 8
/
QRZ Ham Radio Callsign Database - Volume 8.iso
/
pc
/
files
/
t_ka9q
/
ftpsrv.z
/
ftpsrv
Wrap
Text File
|
1996-06-25
|
26KB
|
1,302 lines
head 1.13;
access;
symbols;
locks;
comment @ * @;
1.13
date 93.01.21.06.19.03; author ssampson; state Exp;
branches;
next 1.12;
1.12
date 92.12.28.09.01.43; author karn; state Exp;
branches;
next 1.11;
1.11
date 92.12.21.21.25.54; author karn; state Exp;
branches;
next 1.10;
1.10
date 92.12.17.20.48.07; author karn; state Exp;
branches;
next 1.9;
1.9
date 92.09.07.21.05.39; author karn; state Exp;
branches;
next 1.8;
1.8
date 92.06.03.22.02.42; author karn; state Exp;
branches;
next 1.7;
1.7
date 92.05.29.23.28.14; author karn; state Exp;
branches;
next 1.6;
1.6
date 92.05.19.22.14.12; author karn; state Exp;
branches;
next 1.5;
1.5
date 92.05.19.06.32.12; author karn; state Exp;
branches;
next 1.4;
1.4
date 92.05.03.11.01.42; author karn; state Exp;
branches;
next 1.3;
1.3
date 92.05.01.11.46.36; author karn; state Exp;
branches;
next 1.2;
1.2
date 91.03.16.15.35.04; author karn; state Exp;
branches;
next 1.1;
1.1
date 91.01.27.11.50.36; author karn; state Exp;
branches;
next ;
desc
@src0201
@
1.13
log
@changed access() to stat()
@
text
@/* Internet FTP Server
* Copyright 1991 Phil Karn, KA9Q
*/
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <sys/stat.h>
#ifdef __TURBOC__
#include <io.h>
#include <dir.h>
#endif
#include "global.h"
#include "mbuf.h"
#include "proc.h"
#include "socket.h"
#include "dirutil.h"
#include "commands.h"
#include "files.h"
#include "ftp.h"
#include "ftpserv.h"
#include "md5.h"
static void ftpserv __ARGS((int s,void *unused,void *p));
static int pport __ARGS((struct sockaddr_in *sock,char *arg));
static void ftplogin __ARGS((struct ftpserv *ftp,char *pass));
static int sendit __ARGS((struct ftpserv *ftp,char *command,char *file));
static int recvit __ARGS((struct ftpserv *ftp,char *command,char *file));
/* Command table */
static char *commands[] = {
"user",
"acct",
"pass",
"type",
"list",
"cwd",
"dele",
"name",
"quit",
"retr",
"stor",
"port",
"nlst",
"pwd",
"xpwd", /* For compatibility with 4.2BSD */
"mkd ",
"xmkd", /* For compatibility with 4.2BSD */
"xrmd", /* For compatibility with 4.2BSD */
"rmd ",
"stru",
"mode",
"syst",
"xmd5",
NULLCHAR
};
/* Response messages */
static char banner[] = "220 %s FTP version %s ready at %s\n";
static char badcmd[] = "500 Unknown command '%s'\n";
static char binwarn[] = "100 Warning: type is ASCII and %s appears to be binary\n";
static char unsupp[] = "500 Unsupported command or option\n";
static char givepass[] = "331 Enter PASS command\n";
static char logged[] = "230 Logged in\n";
static char typeok[] = "200 Type %s OK\n";
static char only8[] = "501 Only logical bytesize 8 supported\n";
static char deleok[] = "250 File deleted\n";
static char mkdok[] = "200 MKD ok\n";
static char delefail[] = "550 Delete failed: %s\n";
static char pwdmsg[] = "257 \"%s\" is current directory\n";
static char badtype[] = "501 Unknown type \"%s\"\n";
static char badport[] = "501 Bad port syntax\n";
static char unimp[] = "502 Command not yet implemented\n";
static char bye[] = "221 Goodbye!\n";
static char nodir[] = "553 Can't read directory \"%s\": %s\n";
static char cantopen[] = "550 Can't read file \"%s\": %s\n";
static char sending[] = "150 Opening data connection for %s %s\n";
static char cantmake[] = "553 Can't create \"%s\": %s\n";
static char writerr[] = "552 Write error: %s\n";
static char portok[] = "200 Port command okay\n";
static char rxok[] = "226 File received OK\n";
static char txok[] = "226 File sent OK\n";
static char noperm[] = "550 Permission denied\n";
static char noconn[] = "425 Data connection reset\n";
static char lowmem[] = "421 System overloaded, try again later\n";
static char notlog[] = "530 Please log in with USER and PASS\n";
static char userfirst[] = "503 Login with USER first.\n";
static char okay[] = "200 Ok\n";
static char syst[] = "215 %s Type: L%d Version: %s\n";
static int Sftp = -1; /* Prototype socket for service */
/* Start up FTP service */
int
ftpstart(argc,argv,p)
int argc;
char *argv[];
void *p;
{
struct sockaddr_in lsocket;
int s;
FILE *network;
if(Sftp != -1){
/* Already running! */
return 0;
}
psignal(Curproc,0); /* Don't keep the parser waiting */
chname(Curproc,"FTP listener");
lsocket.sin_family = AF_INET;
lsocket.sin_addr.s_addr = INADDR_ANY;
if(argc < 2)
lsocket.sin_port = IPPORT_FTP;
else
lsocket.sin_port = atoi(argv[1]);
Sftp = socket(AF_INET,SOCK_STREAM,0);
bind(Sftp,(char *)&lsocket,sizeof(lsocket));
listen(Sftp,1);
for(;;){
if((s = accept(Sftp,NULLCHAR,(int *)NULL)) == -1)
break; /* Service is shutting down */
network = fdopen(s,"r+t");
if(availmem() != 0){
fprintf(network,lowmem);
fclose(network);
} else {
/* Spawn a server */
newproc("ftpserv",2048,ftpserv,s,(void *)network,NULL,0);
}
}
return 0;
}
static void
ftpserv(s,n,p)
int s; /* Socket with user connection */
void *n;
void *p;
{
struct ftpserv ftp;
char **cmdp,buf[512],*arg,*cp,*cp1,*file,*mode;
long t;
int i;
struct sockaddr_in socket;
memset((char *)&ftp,0,sizeof(ftp)); /* Start with clear slate */
ftp.control = (FILE *)n;
fclose(stdin);
stdin = fdup(ftp.control);
fclose(stdout);
stdout = fdup(ftp.control);
sockowner(fileno(ftp.control),Curproc); /* We own it now */
/* Set default data port */
i = SOCKSIZE;
getpeername(fileno(ftp.control),(char *)&socket,&i);
socket.sin_port = IPPORT_FTPD;
ASSIGN(ftp.port,socket);
log(fileno(ftp.control),"open FTP");
time(&t);
cp = ctime(&t);
if((cp1 = strchr(cp,'\n')) != NULLCHAR)
*cp1 = '\0';
fprintf(ftp.control,banner,Hostname,Version,cp);
loop: fflush(ftp.control);
if((fgets(buf,sizeof(buf),ftp.control)) == NULLCHAR){
/* He closed on us */
goto finish;
}
if(strlen(buf) == 0){
/* Can't be a legal FTP command */
fprintf(ftp.control,badcmd,buf);
goto loop;
}
rip(buf);
#ifdef UNIX
/* Translate first word to lower case */
for(cp = buf;*cp != ' ' && *cp != '\0';cp++)
*cp = tolower(*cp);
#else
/* Translate entire buffer to lower case */
for(cp = buf;*cp != '\0';cp++)
*cp = tolower(*cp);
#endif
/* Find command in table; if not present, return syntax error */
for(cmdp = commands;*cmdp != NULLCHAR;cmdp++)
if(strncmp(*cmdp,buf,strlen(*cmdp)) == 0)
break;
if(*cmdp == NULLCHAR){
fprintf(ftp.control,badcmd,buf);
goto loop;
}
/* Allow only USER, PASS and QUIT before logging in */
if(ftp.cd == NULLCHAR || ftp.path == NULLCHAR){
switch(cmdp-commands){
case USER_CMD:
case PASS_CMD:
case QUIT_CMD:
break;
default:
fprintf(ftp.control,notlog);
goto loop;
}
}
arg = &buf[strlen(*cmdp)];
while(*arg == ' ')
arg++;
/* Execute specific command */
switch(cmdp-commands){
case USER_CMD:
free(ftp.username);
ftp.username = strdup(arg);
fprintf(ftp.control,givepass);
break;
case TYPE_CMD:
switch(arg[0]){
case 'A':
case 'a': /* Ascii */
ftp.type = ASCII_TYPE;
fprintf(ftp.control,typeok,arg);
break;
case 'l':
case 'L':
while(*arg != ' ' && *arg != '\0')
arg++;
if(*arg == '\0' || *++arg != '8'){
fprintf(ftp.control,only8);
break;
}
ftp.type = LOGICAL_TYPE;
ftp.logbsize = 8;
fprintf(ftp.control,typeok,arg);
break;
case 'B':
case 'b': /* Binary */
case 'I':
case 'i': /* Image */
ftp.type = IMAGE_TYPE;
fprintf(ftp.control,typeok,arg);
break;
default: /* Invalid */
fprintf(ftp.control,badtype,arg);
break;
}
break;
case QUIT_CMD:
fprintf(ftp.control,bye);
goto finish;
case RETR_CMD:
file = pathname(ftp.cd,arg);
switch(ftp.type){
case IMAGE_TYPE:
case LOGICAL_TYPE:
mode = READ_BINARY;
break;
case ASCII_TYPE:
mode = READ_TEXT;
break;
}
if(!permcheck(ftp.path,ftp.perms,RETR_CMD,file)){
fprintf(ftp.control,noperm);
} else if((ftp.fp = fopen(file,mode)) == NULLFILE){
fprintf(ftp.control,cantopen,file,sys_errlist[errno]);
} else {
log(fileno(ftp.control),"RETR %s",file);
if(ftp.type == ASCII_TYPE && isbinary(ftp.fp)){
fprintf(ftp.control,binwarn,file);
}
sendit(&ftp,"RETR",file);
}
free(file);
break;
case STOR_CMD:
file = pathname(ftp.cd,arg);
switch(ftp.type){
case IMAGE_TYPE:
case LOGICAL_TYPE:
mode = WRITE_BINARY;
break;
case ASCII_TYPE:
mode = WRITE_TEXT;
break;
}
if(!permcheck(ftp.path,ftp.perms,STOR_CMD,file)){
fprintf(ftp.control,noperm);
} else if((ftp.fp = fopen(file,mode)) == NULLFILE){
fprintf(ftp.control,cantmake,file,sys_errlist[errno]);
} else {
log(fileno(ftp.control),"STOR %s",file);
recvit(&ftp,"STOR",file);
}
free(file);
break;
case PORT_CMD:
if(pport(&ftp.port,arg) == -1){
fprintf(ftp.control,badport);
} else {
fprintf(ftp.control,portok);
}
break;
#ifndef CPM
case LIST_CMD:
file = pathname(ftp.cd,arg);
if(!permcheck(ftp.path,ftp.perms,RETR_CMD,file)){
fprintf(ftp.control,noperm);
} else if((ftp.fp = dir(file,1)) == NULLFILE){
fprintf(ftp.control,nodir,file,sys_errlist[errno]);
} else {
sendit(&ftp,"LIST",file);
}
free(file);
break;
case NLST_CMD:
file = pathname(ftp.cd,arg);
if(!permcheck(ftp.path,ftp.perms,RETR_CMD,file)){
fprintf(ftp.control,noperm);
} else if((ftp.fp = dir(file,0)) == NULLFILE){
fprintf(ftp.control,nodir,file,sys_errlist[errno]);
} else {
sendit(&ftp,"NLST",file);
}
free(file);
break;
case CWD_CMD:
file = pathname(ftp.cd,arg);
if(!permcheck(ftp.path,ftp.perms,RETR_CMD,file)){
fprintf(ftp.control,noperm);
free(file);
#ifdef MSDOS
} else if ((strcmp(file,"/") == 0) ||
((stat(file, &cwdstat) == 0) &&
(cwdstat.st_mode & S_IFDIR))) {
#else
} else if (stat(file, &cwdstat) == 0 &&
(cwdstat.st_mode & S_IFDIR)) { /* See if it exists */
#endif
/* Succeeded, record in control block */
free(ftp.cd);
ftp.cd = file;
fprintf(ftp.control,pwdmsg,file);
} else {
/* Failed, don't change anything */
fprintf(ftp.control,nodir,file,sys_errlist[errno]);
free(file);
}
break;
case XPWD_CMD:
case PWD_CMD:
fprintf(ftp.control,pwdmsg,ftp.cd);
break;
#else
case LIST_CMD:
case NLST_CMD:
case CWD_CMD:
case XPWD_CMD:
case PWD_CMD:
#endif
case ACCT_CMD:
fprintf(ftp.control,unimp);
break;
case DELE_CMD:
file = pathname(ftp.cd,arg);
if(!permcheck(ftp.path,ftp.perms,DELE_CMD,file)){
fprintf(ftp.control,noperm);
} else if(unlink(file) == 0){
log(fileno(ftp.control),"DELE %s",file);
fprintf(ftp.control,deleok);
} else {
fprintf(ftp.control,delefail,sys_errlist[errno]);
}
free(file);
break;
case PASS_CMD:
if(ftp.username == NULLCHAR)
fprintf(ftp.control,userfirst);
else
ftplogin(&ftp,arg);
break;
#ifndef CPM
case XMKD_CMD:
case MKD_CMD:
file = pathname(ftp.cd,arg);
if(!permcheck(ftp.path,ftp.perms,MKD_CMD,file)){
fprintf(ftp.control,noperm);
#ifdef UNIX
} else if(mkdir(file,0777) == 0){
#else
} else if(mkdir(file) == 0){
#endif
log(fileno(ftp.control),"MKD %s",file);
fprintf(ftp.control,mkdok);
} else {
fprintf(ftp.control,cantmake,file,sys_errlist[errno]);
}
free(file);
break;
case XRMD_CMD:
case RMD_CMD:
file = pathname(ftp.cd,arg);
if(!permcheck(ftp.path,ftp.perms,RMD_CMD,file)){
fprintf(ftp.control,noperm);
} else if(rmdir(file) == 0){
log(fileno(ftp.control),"RMD %s",file);
fprintf(ftp.control,deleok);
} else {
fprintf(ftp.control,delefail,sys_errlist[errno]);
}
free(file);
break;
case STRU_CMD:
if(tolower(arg[0]) != 'f')
fprintf(ftp.control,unsupp);
else
fprintf(ftp.control,okay);
break;
case MODE_CMD:
if(tolower(arg[0]) != 's')
fprintf(ftp.control,unsupp);
else
fprintf(ftp.control,okay);
break;
case SYST_CMD:
fprintf(ftp.control,syst,System,NBBY,Version);
break;
case XMD5_CMD:
file = pathname(ftp.cd,arg);
switch(ftp.type){
case IMAGE_TYPE:
case LOGICAL_TYPE:
mode = READ_BINARY;
break;
case ASCII_TYPE:
mode = READ_TEXT;
break;
}
if(!permcheck(ftp.path,ftp.perms,RETR_CMD,file)){
fprintf(ftp.control,noperm);
} else if((ftp.fp = fopen(file,mode)) == NULLFILE){
fprintf(ftp.control,cantopen,file,sys_errlist[errno]);
} else {
char hash[16];
log(fileno(ftp.control),"XMD5 %s",file);
if(ftp.type == ASCII_TYPE && isbinary(ftp.fp))
fprintf(ftp.control,binwarn,file);
md5hash(ftp.fp,hash,ftp.type == ASCII_TYPE);
fclose(ftp.fp);
ftp.fp = NULLFILE;
fprintf(ftp.control,"200 ");
for(i=0;i<16;i++)
fprintf(ftp.control,"%02x",hash[i] & 0xff);
fprintf(ftp.control," %s\n",file);
}
free(file);
break;
}
#endif
goto loop;
finish:
log(fileno(ftp.control),"close FTP");
/* Clean up */
fclose(ftp.control);
if(ftp.data != NULLFILE)
fclose(ftp.data);
if(ftp.fp != NULLFILE)
fclose(ftp.fp);
free(ftp.username);
free(ftp.path);
free(ftp.cd);
}
/* Shut down FTP server */
int
ftp0(argc,argv,p)
int argc;
char *argv[];
void *p;
{
close_s(Sftp);
Sftp = -1;
return 0;
}
static
int
pport(sock,arg)
struct sockaddr_in *sock;
char *arg;
{
int32 n;
int i;
n = 0;
for(i=0;i<4;i++){
n = atoi(arg) + (n << 8);
if((arg = strchr(arg,',')) == NULLCHAR)
return -1;
arg++;
}
sock->sin_addr.s_addr = n;
n = atoi(arg);
if((arg = strchr(arg,',')) == NULLCHAR)
return -1;
arg++;
n = atoi(arg) + (n << 8);
sock->sin_port = n;
return 0;
}
/* Attempt to log in the user whose name is in ftp->username and password
* in pass
*/
static void
ftplogin(ftp,pass)
struct ftpserv *ftp;
char *pass;
{
char *path;
int anony = 0;
path = mallocw(200);
if((ftp->perms = userlogin(ftp->username,pass,&path,200,&anony))
== -1){
fprintf(ftp->control,noperm);
free(path);
return;
}
/* Set up current directory and path prefix */
#if defined(AMIGAGONE)
ftp->cd = pathname("", path);
ftp->path = strdup(ftp->cd);
free(path);
#else
ftp->cd = path;
ftp->path = strdup(path);
#endif
fprintf(ftp->control,logged);
if(!anony)
log(fileno(ftp->control),"%s logged in",ftp->username);
else
log(fileno(ftp->control),"%s logged in, ID %s",ftp->username,pass);
}
#ifdef MSDOS
/* Illegal characters in a DOS filename */
static char badchars[] = "\"[]:|<>+=;,";
#endif
/* Return 1 if the file operation is allowed, 0 otherwise */
int
permcheck(path,perms,op,file)
char *path;
int perms;
int op;
char *file;
{
#ifdef MSDOS
char *cp;
#endif
if(file == NULLCHAR || path == NULLCHAR)
return 0; /* Probably hasn't logged in yet */
#ifdef MSDOS
/* Check for characters illegal in MS-DOS file names */
for(cp = badchars;*cp != '\0';cp++){
if(strchr(file,*cp) != NULLCHAR)
return 0;
}
#endif
#ifndef MAC
/* The target file must be under the user's allowed search path */
if(strncmp(file,path,strlen(path)) != 0)
return 0;
#endif
switch(op){
case RETR_CMD:
/* User must have permission to read files */
if(perms & FTP_READ)
return 1;
return 0;
case DELE_CMD:
case RMD_CMD:
/* User must have permission to (over)write files */
if(perms & FTP_WRITE)
return 1;
return 0;
case STOR_CMD:
case MKD_CMD:
/* User must have permission to (over)write files, or permission
* to create them if the file doesn't already exist
*/
if(perms & FTP_WRITE)
return 1;
if(access(file,2) == -1 && (perms & FTP_CREATE))
return 1;
return 0;
}
return 0; /* "can't happen" -- keep lint happy */
}
static int
sendit(ftp,command,file)
struct ftpserv *ftp;
char *command;
char *file;
{
long total;
struct sockaddr_in dport;
int s;
s = socket(AF_INET,SOCK_STREAM,0);
dport.sin_family = AF_INET;
dport.sin_addr.s_addr = INADDR_ANY;
dport.sin_port = IPPORT_FTPD;
bind(s,(char *)&dport,SOCKSIZE);
fprintf(ftp->control,sending,command,file);
fflush(ftp->control);
if(connect(s,(char *)&ftp->port,SOCKSIZE) == -1){
fclose(ftp->fp);
ftp->fp = NULLFILE;
close_s(s);
ftp->data = NULLFILE;
fprintf(ftp->control,noconn);
return -1;
}
ftp->data = fdopen(s,"r+");
/* Do the actual transfer */
total = sendfile(ftp->fp,ftp->data,ftp->type,0);
if(total == -1){
/* An error occurred on the data connection */
fprintf(ftp->control,noconn);
shutdown(fileno(ftp->data),2); /* Blow away data connection */
fclose(ftp->data);
} else {
fprintf(ftp->control,txok);
}
fclose(ftp->fp);
ftp->fp = NULLFILE;
fclose(ftp->data);
ftp->data = NULLFILE;
if(total == -1)
return -1;
else
return 0;
}
static int
recvit(ftp,command,file)
struct ftpserv *ftp;
char *command;
char *file;
{
struct sockaddr_in dport;
long total;
int s;
s = socket(AF_INET,SOCK_STREAM,0);
dport.sin_family = AF_INET;
dport.sin_addr.s_addr = INADDR_ANY;
dport.sin_port = IPPORT_FTPD;
bind(s,(char *)&dport,SOCKSIZE);
fprintf(ftp->control,sending,command,file);
fflush(ftp->control);
if(connect(s,(char *)&ftp->port,SOCKSIZE) == -1){
fclose(ftp->fp);
ftp->fp = NULLFILE;
close_s(s);
ftp->data = NULLCHAR;
fprintf(ftp->control,noconn);
return -1;
}
ftp->data = fdopen(s,"r+");
/* Do the actual transfer */
total = recvfile(ftp->fp,ftp->data,ftp->type,0);
#ifdef CPM
if(ftp->type == ASCII_TYPE)
putc(CTLZ,ftp->fp);
#endif
if(total == -1) {
/* An error occurred while writing the file */
fprintf(ftp->control,writerr,sys_errlist[errno]);
shutdown(fileno(ftp->data),2); /* Blow it away */
fclose(ftp->data);
} else {
fprintf(ftp->control,rxok);
fclose(ftp->data);
}
ftp->data = NULLFILE;
fclose(ftp->fp);
ftp->fp = NULLFILE;
if(total == -1)
return -1;
else
return 0;
}
@
1.12
log
@Pass ascii flag to md5hash()
@
text
@d7 1
d332 4
a335 3
#ifdef MSDOS
/* Don'tcha just LOVE %%$#@@!! MS-DOS? */
} else if(strcmp(file,"/") == 0 || access(file,0) == 0){
d337 2
a338 1
} else if(access(file,0) == 0){ /* See if it exists */
@
1.11
log
@Move md5 file hashing into common subroutine
@
text
@d447 1
a447 1
md5hash(ftp.fp,hash);
@
1.10
log
@Add XMD5 command to produce MD5 hash of a file. Should be extended
to handle a seek offset and length. Also need to think about ascii
file standards (netascii?)
@
text
@d441 1
a441 3
MD5_CTX md;
char *buf;
int len;
d444 1
a444 1
if(ftp.type == ASCII_TYPE && isbinary(ftp.fp)){
d446 2
a447 8
}
MD5Init(&md);
buf = malloc(BUFSIZ);
while((len = fread(buf,1,BUFSIZ,ftp.fp)) != 0){
MD5Update(&md,buf,len);
pwait(NULL);
}
free(buf);
a449 1
MD5Final(&md);
d452 2
a453 2
fprintf(ftp.control,"%02x",md.digest[i]);
fprintf(ftp.control,"\n");
@
1.9
log
@Implement SYST command, also add echoing of bad commands
@
text
@d20 1
d52 1
d424 41
@
1.8
log
@s920603
@
text
@d50 1
d56 1
a56 1
static char badcmd[] = "500 Unknown command\n";
d85 1
d171 1
a171 1
fprintf(ftp.control,badcmd);
d189 1
a189 1
fprintf(ftp.control,badcmd);
d419 3
@
1.7
log
@s920529
@
text
@d144 4
@
1.6
log
@src0519
@
text
@d631 1
@
1.5
log
@src0518
@
text
@d120 1
a120 1
if(availmem() < Memthresh){
@
1.4
log
@src0503
@
text
@a140 1
FILE *network;
a141 2
network = (FILE *)n;
d143 1
a143 1
ftp.data = NULLFILE;
d145 1
a145 2
sockowner(fileno(network),Curproc); /* We own it now */
ftp.control = network;
d148 1
a148 1
getpeername(fileno(network),(char *)&socket,&i);
d152 1
a152 1
log(fileno(network),"open FTP");
d157 3
a159 2
fprintf(network,banner,Hostname,Version,cp);
loop: if((fgets(buf,sizeof(buf),network)) == NULLCHAR){
d575 1
d621 1
@
1.3
log
@src0501
@
text
@d119 1
a119 2
network = fdopen(s,"r+");
seteol(network,eolseq(s));
a143 2
seteol(network,eolseq(fileno(network)));
fmode(network,STREAM_ASCII);
@
1.2
log
@src0318
@
text
@d96 1
d119 2
d122 2
a123 2
usprintf(s,lowmem);
shutdown(s,1);
d126 1
a126 1
newproc("ftpserv",2048,ftpserv,s,NULL,NULL,0);
d132 1
a132 1
ftpserv(s,unused,p)
d134 1
a134 1
void *unused;
d140 1
a140 1
int cnt,i;
d142 1
d144 4
a147 1
sockmode(s,SOCK_ASCII);
d149 1
a149 1
ftp.data = -1;
d151 2
a152 2
sockowner(s,Curproc); /* We own it now */
ftp.control = s;
d155 1
a155 1
getpeername(s,(char *)&socket,&i);
d159 1
a159 1
log(s,"open FTP");
d164 2
a165 2
usprintf(s,banner,Hostname,Version,cp);
loop: if((cnt = recvline(s,buf,sizeof(buf))) == -1){
d169 1
a169 1
if(cnt == 0){
d171 1
a171 1
usprintf(ftp.control,badcmd);
d189 1
a189 1
usprintf(ftp.control,badcmd);
d200 1
a200 1
usprintf(ftp.control,notlog);
d213 1
a213 1
usprintf(ftp.control,givepass);
d220 1
a220 1
usprintf(ftp.control,typeok,arg);
d227 1
a227 1
usprintf(ftp.control,only8);
d232 1
a232 1
usprintf(ftp.control,typeok,arg);
d239 1
a239 1
usprintf(ftp.control,typeok,arg);
d242 1
a242 1
usprintf(ftp.control,badtype,arg);
d247 1
a247 1
usprintf(ftp.control,bye);
d261 1
a261 1
usprintf(ftp.control,noperm);
d263 1
a263 1
usprintf(ftp.control,cantopen,file,sys_errlist[errno]);
d265 1
a265 1
log(ftp.control,"RETR %s",file);
d267 1
a267 1
usprintf(ftp.control,binwarn,file);
d285 1
a285 1
usprintf(ftp.control,noperm);
d287 1
a287 1
usprintf(ftp.control,cantmake,file,sys_errlist[errno]);
d289 1
a289 1
log(ftp.control,"STOR %s",file);
d296 1
a296 1
usprintf(ftp.control,badport);
d298 1
a298 1
usprintf(ftp.control,portok);
d305 1
a305 1
usprintf(ftp.control,noperm);
d307 1
a307 1
usprintf(ftp.control,nodir,file,sys_errlist[errno]);
d316 1
a316 1
usprintf(ftp.control,noperm);
d318 1
a318 1
usprintf(ftp.control,nodir,file,sys_errlist[errno]);
d327 1
a327 1
usprintf(ftp.control,noperm);
d338 1
a338 1
usprintf(ftp.control,pwdmsg,file);
d341 1
a341 1
usprintf(ftp.control,nodir,file,sys_errlist[errno]);
d347 1
a347 1
usprintf(ftp.control,pwdmsg,ftp.cd);
d357 1
a357 1
usprintf(ftp.control,unimp);
d362 1
a362 1
usprintf(ftp.control,noperm);
d364 2
a365 2
log(ftp.control,"DELE %s",file);
usprintf(ftp.control,deleok);
d367 1
a367 1
usprintf(ftp.control,delefail,sys_errlist[errno]);
d373 1
a373 1
usprintf(ftp.control,userfirst);
d382 1
a382 1
usprintf(ftp.control,noperm);
d388 2
a389 2
log(ftp.control,"MKD %s",file);
usprintf(ftp.control,mkdok);
d391 1
a391 1
usprintf(ftp.control,cantmake,file,sys_errlist[errno]);
d399 1
a399 1
usprintf(ftp.control,noperm);
d401 2
a402 2
log(ftp.control,"RMD %s",file);
usprintf(ftp.control,deleok);
d404 1
a404 1
usprintf(ftp.control,delefail,sys_errlist[errno]);
d410 1
a410 1
usprintf(ftp.control,unsupp);
d412 1
a412 1
usprintf(ftp.control,okay);
d416 1
a416 1
usprintf(ftp.control,unsupp);
d418 1
a418 1
usprintf(ftp.control,okay);
d424 1
a424 1
log(ftp.control,"close FTP");
d426 3
a428 3
close_s(ftp.control);
if(ftp.data != -1)
close_s(ftp.data);
d487 1
a487 1
usprintf(ftp->control,noperm);
d501 1
a501 1
usprintf(ftp->control,logged);
d503 1
a503 1
log(ftp->control,"%s logged in",ftp->username);
d505 1
a505 1
log(ftp->control,"%s logged in, ID %s",ftp->username,pass);
d573 1
d575 1
a575 1
ftp->data = socket(AF_INET,SOCK_STREAM,0);
d579 3
a581 3
bind(ftp->data,(char *)&dport,SOCKSIZE);
usprintf(ftp->control,sending,command,file);
if(connect(ftp->data,(char *)&ftp->port,SOCKSIZE) == -1){
d584 3
a586 3
close_s(ftp->data);
ftp->data = -1;
usprintf(ftp->control,noconn);
d589 1
d595 3
a597 2
usprintf(ftp->control,noconn);
shutdown(ftp->data,2); /* Blow away data connection */
d599 1
a599 1
usprintf(ftp->control,txok);
d603 2
a604 2
close_s(ftp->data);
ftp->data = -1;
d618 1
d620 1
a620 1
ftp->data = socket(AF_INET,SOCK_STREAM,0);
d624 3
a626 3
bind(ftp->data,(char *)&dport,SOCKSIZE);
usprintf(ftp->control,sending,command,file);
if(connect(ftp->data,(char *)&ftp->port,SOCKSIZE) == -1){
d629 3
a631 3
close_s(ftp->data);
ftp->data = -1;
usprintf(ftp->control,noconn);
d634 1
d643 3
a645 2
usprintf(ftp->control,writerr,sys_errlist[errno]);
shutdown(ftp->data,2); /* Blow it away */
d647 2
a648 2
usprintf(ftp->control,rxok);
close_s(ftp->data);
d650 1
a650 1
ftp->data = -1;
@
1.1
log
@Initial revision
@
text
@d13 1
d15 3
a19 3
#include "proc.h"
#include "dirutil.h"
#include "commands.h"
a465 82
/* Subroutine for logging in the user whose name is name and password is pass.
The buffer path should be long enough to keep a line from the userfile.
If pwdignore is true, the password check will be overridden.
The return value is the permissions field or -1 if the login failed.
Path is set to point at the path field, and pwdignore will be true if no
particular password was needed for this user.
*/
int
userlogin(name,pass,path,len,pwdignore)
char *name;
char *pass;
char **path;
int len; /* Length of buffer pointed at by *path */
int *pwdignore;
{
char *cp,*cp1;
FILE *fp;
int anony,perm;
if((fp = fopen(Userfile,READ_TEXT)) == NULLFILE)
/* Userfile doesn't exist */
return -1;
while(fgets(*path,len,fp),!feof(fp)){
if(*path[0] == '#')
continue; /* Comment */
if((cp = strchr(*path,' ')) == NULLCHAR)
/* Bogus entry */
continue;
*cp++ = '\0'; /* Now points to password */
if(stricmp(name,*path) == 0)
break; /* Found user name */
}
if(feof(fp)){
/* User name not found in file */
fclose(fp);
return -1;
}
fclose(fp);
/* Look for space after password field in file */
if((cp1 = strchr(cp,' ')) == NULLCHAR)
/* Invalid file entry */
return -1;
*cp1++ = '\0'; /* Now points to path field */
anony = *pwdignore;
if(strcmp(cp,"*") == 0)
anony = 1; /* User ID is password-free */
if(!anony && strcmp(cp,pass) != 0)
/* Password required, but wrong one given */
return -1;
if((cp = strchr(cp1,' ')) == NULLCHAR)
/* Permission field missing */
return -1;
*cp++ = '\0'; /* now points to permission field */
perm = atoi(cp);
#if defined(AMIGA)
/*
* Well, on the Amiga, a file can be referenced by many names:
* device names (DF0:) or volume names (My_Disk:). This hunk of code
* passed the pathname specified in the ftpusers file, and gets the
* absolute path copied into the user's buffer. We really should just
* allocate the buffer and return a pointer to it, since the caller
* really doesn't have a good idea how long the path string is..
*/
cp1 = pathname("", cp1);
if (cp1)
strcpy(*path, cp1);
else
**path = '\0';
free(cp1);
#else
strcpy(*path,cp1);
/* Convert any backslashes to forward slashes, for backward
* compatibility with the old NET
*/
while((cp = strchr(*path,'\\')) != NULLCHAR)
*cp = '/';
#endif
*pwdignore = anony;
/* Finally return the permission bits */
return perm;
}
@